package auctionhaus

import grails.test.*
import com.auctionhaus.Listing
import com.auctionhaus.Customer
import com.auctionhaus.Bid

class BidServiceIntegrationTests extends GroovyTestCase {
    def BidService

    transient String sellerEmail =  "katy@perry.com"
    transient String buyerEmail =  "russell@brand.com"
    transient String cheapBuyerEmail = "lindsay@lohan.com"
    transient String goodPassword = "password"
    transient String invalid = "invalid"

    protected void setUp() {
        super.setUp()
        deleteAllFromDatabase()
        def seller = new Customer(emailAddress: sellerEmail, password: goodPassword, date: new Date()).save()
        def buyer = new Customer(emailAddress: buyerEmail, password: goodPassword, date: new Date()).save()
        def cheapBuyer = new Customer(emailAddress: cheapBuyerEmail, password: goodPassword, date: new Date()).save()

        new Listing(creationDate:new Date(), listName: 'Fireworks Music Video',
                description: 'Collectors Edition',
                endDateTime: new Date() + 5,
                startBidPrice: 15,
                seller: seller).save()

        new Listing(creationDate:new Date(), listName: 'Expired Item',
                description: 'So Yesterday',
                endDateTime: new Date(System.currentTimeMillis()+1),
                startBidPrice: 15,
                seller: seller).save()
    }

    protected void tearDown() {
        super.tearDown()
        deleteAllFromDatabase()
    }
    private void deleteAllFromDatabase() {

        Listing.findAll().each {x -> x.delete() }
        Customer.findAll().each {x -> x.delete() }
    }
    //S-3: Create a Grails service method that supports bidding on a listing (integration test).
    void testPlaceBidOnListing() {
        def bid = BidService.placeBidOnListing('Fireworks Music Video', buyerEmail, goodPassword, 16.00 )
        def foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress(buyerEmail), 16)
        assertEquals bid, foundBid

    }
    //S-3: Create a Grails service method that supports bidding on a listing (integration test).
    void testPlaceBidOnListingWithInvalidAmount() {
        def bid = BidService.placeBidOnListing('Fireworks Music Video', cheapBuyerEmail, goodPassword, 15.25 )
        def foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress(cheapBuyerEmail), 15.25)
        assertNull bid
        assertNull foundBid

    }
    //S-3: Create a Grails service method that supports bidding on a listing (integration test).
    void testPlaceBidOnListingWithValidIncrement() {
        def bid = BidService.placeBidOnListing('Fireworks Music Video', cheapBuyerEmail, goodPassword, 15.45 )
        def foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress(cheapBuyerEmail), 15.45)
        assertNull bid
        assertNull foundBid

        bid = BidService.placeBidOnListing('Fireworks Music Video', cheapBuyerEmail, goodPassword, 15.5 )
        foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress(cheapBuyerEmail), 15.5)
        assertEquals bid, foundBid

    }
    //S-5: The Grails service method for S-3 must validate the bidders username and password before creating the bid (integration test)
    void testPlaceBidOnListingWithInvalidEmail() {
        //incorrect email address
        def bid = BidService.placeBidOnListing('Fireworks Music Video', "notRussell@brand.com", goodPassword, 16 )
        def foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress("notRussell@brand.com"), 16)
        assertNull bid
        assertNull foundBid

        //correct email address
        bid = BidService.placeBidOnListing('Fireworks Music Video', "russell@brand.com", goodPassword, 16 )
        foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress("russell@brand.com"), 16)
        assertEquals bid, foundBid

        //correct case insensitive email address
        bid = BidService.placeBidOnListing('Fireworks Music Video', "RuSseLl@brANd.com", goodPassword, 17 )
        assertNotNull bid
    }

    void testPlaceBidOnListingWithInvalidPassword() {
        //invalid password
        def bid = BidService.placeBidOnListing('Fireworks Music Video', buyerEmail, invalid, 20 )
        def foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress(buyerEmail), 20)
        assertNull bid
        assertNull foundBid

        //case sensitive password
        bid = BidService.placeBidOnListing('Fireworks Music Video', "russell@brand.com", "passWORD", 20 )
        assertNull bid

        //valid password
        bid = BidService.placeBidOnListing('Fireworks Music Video', "russell@brand.com", goodPassword, 20 )
        foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress("russell@brand.com"), 20)
        assertEquals bid, foundBid
    }

    //C-4: When a listing completes it can no longer accept any more bids.
    // Verify this by testing through the service method created for S-3 (integration test).
    void testPlaceBidOnCompletedListing() {
        //expired listing
     //   wait(10)
        def bid = BidService.placeBidOnListing('Expired Item', buyerEmail, goodPassword, 20 )
        def foundBid = Bid.findByBuyerAndAmount(Customer.findByEmailAddress(buyerEmail), 20)
        assertNull bid
        assertNull foundBid

    }

}
